<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="umsroot.css">
<TITLE>
Errors
</TITLE>
</HEAD>
<BODY >
<A HREF="umsroot071.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot070.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot073.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2 CLASS="section"><A NAME="htoc177">13.2</A>&nbsp;&nbsp;Errors</H2><UL>
<LI><A HREF="umsroot072.html#toc107">Error Handlers</A>
<LI><A HREF="umsroot072.html#toc108">Arguments of Error Handlers</A>
<LI><A HREF="umsroot072.html#toc109">User Defined Errors</A>
</UL>

<A NAME="@default714"></A>
Error handling is one particular use of events.
The main property of error events is that they have a culprit goal,
ie. the goal that detected or caused the error.
The error handler obtains that goal as an argument.<BR>
<BR>
The errors that the system raises have numerical identifiers,
as documented in appendix <A HREF="umsroot147.html#chaperrors">C</A>.
User-defined errors have atomic names, they are the same as events.
Whenever an error occurs, the ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> system identifies the type of error, and
calls the appropriate handler. For each type of error, it is possible
for the user to define a separate handler. This definition will replace
the default error handling routine for that particular error - all other
errors will still
be handled by their respective
handlers.
It is of
course possible to associate the same user defined error handler to more
than one error type.<BR>
<BR>
When a goal is called and produces an error, execution of the goal
is aborted and the appropriate error handler is invoked.
This invocation of the error handler is seen as <I>replacing</I>
the invocation of the erroneous goal:
<UL CLASS="itemize"><LI CLASS="li-itemize">
If the error handler fails it has the same effect as if the
erroneous goal failed.
<LI CLASS="li-itemize">If the error handler succeeds, possibly binding some variables,
the execution continues at the point behind the call of the erroneous goal.
<LI CLASS="li-itemize">If the handler calls <A HREF="../bips/kernel/control/exit_block-1.html"><B>exit_block/1</B></A><A NAME="@default715"></A>, it has the same effect as if
this was done by the erroneous goal itself.
</UL>
For errors that are classified as warnings the second point is somewhat
different: If the handler succeeds, the goal that raised the warning
is allowed to continue execution.<BR>
<BR>
Apart from binding variables in the erroneous goal, error handlers can
also leave backtrack points. However, if the error was raised by
an external or a builtin that is implemented as an external, these
choicepoints are discarded<SUP><A NAME="text21" HREF="umsroot070.html#note21">3</A></SUP>.<BR>
<BR>
<A NAME="toc107"></A>
<H3 CLASS="subsection"><A NAME="htoc178">13.2.1</A>&nbsp;&nbsp;Error Handlers</H3>
The predicate <A HREF="../bips/kernel/event/set_event_handler-2.html"><B>set_event_handler/2</B></A><A NAME="@default716"></A> is used to assign a procedure as
an error handler. The call
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
set_event_handler(ErrorId, PredSpec)
</PRE></BLOCKQUOTE>
<A NAME="@default717"></A>
sets the event handler for error type <I>ErrorId</I> to the procedure specified by
<I>PredSpec</I>, which must be of the form <I>Name/Arity</I>.<BR>
<BR>
<A NAME="@default718"></A>
The corresponding predicate <A HREF="../bips/kernel/event/get_event_handler-3.html"><B>get_event_handler/3</B></A><A NAME="@default719"></A> may be used to identify
the current handler for a particular error. The call
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
get_event_handler(ErrorId, PredSpec, HomeModule)
</PRE></BLOCKQUOTE>
will, provided <I>ErrorId</I> is a valid error identifier, unify <I>PredSpec</I> 
with the
specification of the current handler for error <I>ErrorId</I> in the form
Name/Arity, and <I>HomeModule</I> will be unified with the module where the
error handler has been defined. Note that this error handler might not be
visible from every module and therefore may not be callable.<BR>
<BR>
To re-install the system's error handler in case the user error handler is
no longer needed, <A HREF="../bips/kernel/event/reset_event_handler-1.html"><B>reset_event_handler/1</B></A><A NAME="@default720"></A> should be used.
<A HREF="../bips/kernel/event/reset_error_handlers-0.html"><B>reset_error_handlers/0</B></A><A NAME="@default721"></A> resets all error handlers to their default values.<BR>
<BR>
To enable the user to conveniently write predicates with error checking
the built-ins
<A NAME="@default722"></A>
<A NAME="@default723"></A>
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
error(ErrorId, Goal)
error(ErrorId, Goal, Module)
</PRE></BLOCKQUOTE>
are provided to raise the error <I>ErrorId</I> (an error number or a name atom)
with the culprit <I>Goal</I>.
Inside tool procedures it is usually necessary to use <A HREF="../bips/kernel/event/error-3.html"><B>error/3</B></A><A NAME="@default724"></A>
in order to pass the caller module to the error handler.
Typical error checking code looks like this
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
increment(X, X1) :-
        ( integer(X) -&gt;
            X1 is X + 1
        ;
            error(5, increment(X, X1))
        ).
</PRE></BLOCKQUOTE>
The predicate <A HREF="../bips/kernel/event/current_error-1.html"><B>current_error/1</B></A><A NAME="@default725"></A>
<A NAME="@default726"></A>
can be used to yield all valid error numbers, a valid error is that one
to which an error message and an error handler are associated.
The predicate <A HREF="../bips/kernel/event/error_id-2.html"><B>error_id/2</B></A><A NAME="@default727"></A>
<A NAME="@default728"></A>
<A NAME="@default729"></A>
gives the corresponding error message to the specified error number.
To ease the search for the appropriate error number,
the library <B>util</B> contains the predicate
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
util:list_error(Text, N, Message)
</PRE></BLOCKQUOTE>
which returns on backtracking all the errors whose error message
contains the string <I>Text</I>.<BR>
<BR>
The ability to define any Prolog predicate as the error handler permits a
great deal of flexibility in error handling. However, this flexibility
should be used with caution. The action of an error handler could have side
effects altering the correctness of a program; indeed it could be responsible
for further errors being introduced. One particular area of danger is in the
use of input and output streams by error handlers.
<BR>
<BR>
<A NAME="toc108"></A>
<H3 CLASS="subsection"><A NAME="htoc179">13.2.2</A>&nbsp;&nbsp;Arguments of Error Handlers</H3>
An error handler has 4 optional arguments.
<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
The first argument is the number or atom that identifies the error.
<LI CLASS="li-enumerate">The second argument is
the culprit (a structure corresponding to the call which caused the
error).
For instance, if,
say, a type error occurs upon calling the second goal of the procedure
<TT>p(2, Z)</TT>:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
 p(X, Y) :- a(X), b(X, Y), c(Y).
</PRE></BLOCKQUOTE>
the structure given to the error handler is <TT>b(2, Y)</TT>.
Note that the handler could bind Y which would have the same effect
as if <TT>b/2</TT> had done the binding.<BR>
<BR>
<LI CLASS="li-enumerate">The third argument is only defined for a subset of the existing errors.
If the error occurred inside a tool body, it holds the caller module,
otherwise it is identical to the fourth argument<SUP><A NAME="text22" HREF="umsroot070.html#note22">4</A></SUP>.<BR>
<BR>
<LI CLASS="li-enumerate">The fourth argument is the lookup module for the culprit goal. This
is needed for example when the handler wants to call the culprit reliably,
using a qualified call via <A HREF="../bips/kernel/control/N-2.html"><B>: /2</B></A><A NAME="@default730"></A>.
</OL>
The error handler is free to ignore some of these arguments,
i.e. it can have any arity from 0 to 4.
The first argument is provided for the case that the same procedure serves
as the handler for several error types - then it can distinguish
which is the actual error type.
<A NAME="@default731"></A>
An error handler is just an ordinary Prolog procedure and thus within
it a call may be made to any other procedure, or any built in predicate;
this in particular means that a call to <A HREF="../bips/kernel/control/exit_block-1.html"><B>exit_block/1</B></A><A NAME="@default732"></A> may be
made (see the section on the <A HREF="../bips/kernel/control/block-3.html"><B>block/3</B></A><A NAME="@default733"></A>
predicate).<A NAME="@default734"></A> This will work
'through' the call to the error handler, and so an exit may be made from
within the handler out of the current block (i.e. back to the corresponding
call of the <A HREF="../bips/kernel/control/block-3.html"><B>block/3</B></A><A NAME="@default735"></A> predicate).
Specifying the predicates <A HREF="../bips/kernel/control/true-0.html"><B>true/0</B></A><A NAME="@default736"></A> or <A HREF="../bips/kernel/control/fail-0.html"><B>fail/0</B></A><A NAME="@default737"></A> as error handlers
will make the erroneous predicate succeed (without binding
any further variables) or fail respectively.<BR>
<BR>
The following two templates are the most common for error handlers.
The first simply prints an error message and aborts:
<PRE CLASS="verbatim">
my_error_handler(ErrorId, Goal, ContextModule) :-
        printf(error, "Error %w in %w in module %w%n",
                [ErrorId,Goal,ContextModule]),
        abort.
</PRE>The following handler tries to repair the error and call the goal again:
<PRE CLASS="verbatim">
my_error_repair_handler(ErrorId, Goal, ContextModule, LookupModule) :-
        % repair the error
        ... some code to repair the cause for the error ...
        % try call the erroneous goal again
        LookupModule : Goal @ ContextModule.
</PRE>
<A NAME="toc109"></A>
<H3 CLASS="subsection"><A NAME="htoc180">13.2.3</A>&nbsp;&nbsp;User Defined Errors</H3>
<A NAME="user-errors"></A>
<A NAME="@default738"></A>
The following example illustrates the use of a user-defined error.
We declare a handler for the event 'Invalid command' and
raise the new error in the application code.
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
% Command error handler - output invalid command, sound bell and abort
command_error_handler(_, Command) :-
        printf("\007\nInvalid command: %w\n", [Command]),
        abort.

% Activate the handler
:- set_event_handler('Invalid command', command_error_handler/2).

% top command processing loop
go :-
        writeln("Enter command."),
        read(Command),
        ( valid_command(Command)-&gt;
            process_command(Command),
            go
        ;
            error('Invalid command',Command)  % Call the error handler
        ).

% Some valid commands
valid_command(start).
valid_command(stop).
</PRE></BLOCKQUOTE>
<HR>
<A HREF="umsroot071.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="umsroot070.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="umsroot073.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
